export class WebSocketAdapter {
    constructor(options) {
        this.options = options;
        this.socket = null;
        this.supportsSend = true;

        // 重连配置
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = this.options.maxReconnectAttempts ?? 5;
        this.reconnectInterval = this.options.reconnectInterval ?? 1000;
        this.maxReconnectInterval = this.options.maxReconnectInterval ?? 30000;
        this.reconnectDecay = this.options.reconnectDecay ?? 1.5;

        // 心跳配置
        this.heartbeatInterval = this.options.heartbeatInterval ?? 30000; // 心跳发送间隔
        this.heartbeatTimeout = this.options.heartbeatTimeout ?? 10000;    // 心跳响应超时时间
        this.heartbeatTimer = null;    // 心跳发送定时器
        this.heartbeatTimeoutTimer = null; // 心跳检测定时器

        // 状态管理
        this.isExplicitDisconnect = false;
        this.reconnectTimer = null;
        this.networkListenersAdded = false; // 网络状态监听标记
    }

    connect({ onMessage, onOpen, onClose, onError, onReconnecting }) {
        // 绑定事件回调
        this.options.onMessage = onMessage;
        this.options.onOpen = onOpen;
        this.options.onClose = onClose;
        this.options.onError = onError;
        this.options.onReconnecting = onReconnecting;

        this._connectSocket();
    }

    /* ------------------------ 核心连接逻辑 ------------------------ */
    _connectSocket() {
        this.isExplicitDisconnect = false;
        this.socket = new WebSocket(this.options.url);

        // 绑定基础事件
        this.socket.onopen = this._handleOpen.bind(this);
        this.socket.onmessage = (e) => {
            this._handleMessage(e);
            this._resetHeartbeat(); // 收到消息时重置心跳检测
        };
        this.socket.onclose = this._handleClose.bind(this);
        this.socket.onerror = this._handleError.bind(this);
    }

    /* ------------------------ 心跳机制 ------------------------ */
    _startHeartbeat() {
        // 发送心跳包
        this.heartbeatTimer = setInterval(() => {
            if (this.socket?.readyState === WebSocket.OPEN) {
                this.send({ type: 'ping' }); // 发送应用层心跳包

                // 启动心跳超时检测
                this.heartbeatTimeoutTimer = setTimeout(() => {
                    console.warn('心跳超时，主动断开连接');
                    this.socket.close(); // 触发重连逻辑
                }, this.heartbeatTimeout);
            }
        }, this.heartbeatInterval);
    }

    _resetHeartbeat() {
        // 收到任何消息（包括 pong）时重置心跳检测
        if (this.heartbeatTimeoutTimer) {
            clearTimeout(this.heartbeatTimeoutTimer);
            this.heartbeatTimeoutTimer = null;
        }
    }

    _stopHeartbeat() {
        clearInterval(this.heartbeatTimer);
        clearTimeout(this.heartbeatTimeoutTimer);
        this.heartbeatTimer = null;
        this.heartbeatTimeoutTimer = null;
    }

    /* ------------------------ 网络状态检测 ------------------------ */
    _handleNetworkChange = () => {
        if (navigator.onLine) {
            console.log('网络恢复，尝试重新连接');
            window.removeEventListener('online', this._handleNetworkChange);
            this.networkListenersAdded = false;
            this._scheduleReconnect();
        }
    };

    _checkNetworkBeforeReconnect() {
        if (!navigator.onLine) {
            console.log('网络离线，暂停重连');
            if (!this.networkListenersAdded) {
                window.addEventListener('online', this._handleNetworkChange);
                this.networkListenersAdded = true;
            }
            return false;
        }
        return true;
    }

    /* ------------------------ 事件处理器 ------------------------ */
    _handleOpen() {
        this.reconnectAttempts = 0;
        this._stopHeartbeat();
        this._startHeartbeat();
        this.options.onOpen?.();
    }

    _handleMessage(event) {
        const data = this.options.format === 'json' ? JSON.parse(event.data) : event.data;
        // 处理服务器返回的 pong 响应（可选）
        if (data.type === 'pong') {
            this._resetHeartbeat();
        }
        this.options.onMessage?.(data);
    }

    _handleClose(event) {
        this._stopHeartbeat();
        this.options.onClose?.(event);

        if (!this.isExplicitDisconnect && this.reconnectAttempts < this.maxReconnectAttempts) {
            if (this._checkNetworkBeforeReconnect()) {
                this._scheduleReconnect();
            }
        }
    }

    _handleError(error) {
        this.options.onError?.(error);
    }

    /* ------------------------ 重连逻辑 ------------------------ */
    _scheduleReconnect() {
        if (this.reconnectTimer) clearTimeout(this.reconnectTimer);

        const delay = Math.min(
            this.reconnectInterval * (this.reconnectDecay ** this.reconnectAttempts),
            this.maxReconnectInterval
        );

        // 触发重连通知事件
        this.options.onReconnecting?.(this.reconnectAttempts + 1, delay);

        this.reconnectTimer = setTimeout(() => {
            this.reconnectAttempts++;
            console.log(`第 ${this.reconnectAttempts} 次重连尝试...`);
            this._connectSocket();
        }, delay);
    }

    /* ------------------------ 公开方法 ------------------------ */
    send(data) {
        if (this.socket?.readyState === WebSocket.OPEN) {
            const payload = this.options.format === 'json' ? JSON.stringify(data) : data;
            this.socket.send(payload);
        }
    }

    disconnect() {
        this.isExplicitDisconnect = true;
        this._stopHeartbeat();
        window.removeEventListener('online', this._handleNetworkChange); // 清理网络监听
        if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
        if (this.socket) this.socket.close();
    }
}